[AWS Glue]既存のGlueテーブルに対するクローラーをCloudFormationで作成してみた
こんにちは、CX事業本部の若槻です。
AWS Glueではクローラーを使うことにより、指定したデータソースを解析して必要なパーティションやカラムなどのを持つGlueテーブルを自動作成し、継続的に更新させることができます。
一方で、手動で作成した既存のGlueテーブルを更新対象としたクローラーを作成することも可能です。
今回は、既存のGlueテーブルに対するクローラーをCloudFormationで作成してみました。
やってみた
まず最初に以降のコマンド実行で使用する変数を定義しておきます。
% AWS_REGION=ap-northeast-1 % ACCOUNT_ID=$(aws sts get-caller-identity | jq -r ".Account") % RAW_DATA_BUCKET=s3://devices-raw-data-${ACCOUNT_ID}-${AWS_REGION} % GLUE_DATABASE_NAME=devices_data_analystics % RAW_DATA_GLUE_TABLE_NAME=devices_raw_data % CRAWLER_NAME=devices-data-analytics
環境構築
動作確認環境を作成します。
CloudFormationスタック
CloudFormationスタックのテンプレートです。
AWSTemplateFormatVersion: '2010-09-09' Resources: DevicesRawDataBucket: Type: AWS::S3::Bucket Properties: BucketName: !Sub devices-raw-data-${AWS::AccountId}-${AWS::Region} DevicesDataAnalyticsGlueDatabase: Type: AWS::Glue::Database Properties: CatalogId: !Ref AWS::AccountId DatabaseInput: Name: devices_data_analystics DevicesRawDataGlueTable: Type: AWS::Glue::Table Properties: CatalogId: !Ref AWS::AccountId DatabaseName: !Ref DevicesDataAnalyticsGlueDatabase TableInput: Name: devices_raw_data TableType: EXTERNAL_TABLE Parameters: has_encrypted_data: false serialization.encoding: utf-8 EXTERNAL: true StorageDescriptor: OutputFormat: org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat Columns: - Name: device_id Type: string - Name: timestamp Type: bigint - Name: state Type: boolean InputFormat: org.apache.hadoop.mapred.TextInputFormat Location: !Sub s3://${DevicesRawDataBucket}/raw-data SerdeInfo: Parameters: paths: device_id, timestamp, state SerializationLibrary: org.apache.hive.hcatalog.data.JsonSerDe PartitionKeys: - Name: year Type: string - Name: month Type: string - Name: day Type: string DevicesDataAnalyticsGlueCrawler: Type: AWS::Glue::Crawler Properties: Name: devices-data-analytics Role: !Sub arn:aws:iam::${AWS::AccountId}:role/service-role/AWSGlueServiceRole-DefaultRole Targets: CatalogTargets: - DatabaseName: !Ref DevicesDataAnalyticsGlueDatabase Tables: - !Ref DevicesRawDataGlueTable SchemaChangePolicy: DeleteBehavior: LOG
DevicesDataAnalyticsGlueCrawler
がクローラーのリソース定義となります。Properties.Targets.CatalogTargets
でクロール対象としたい既存のGlueテーブルを指定できます。
Properties.SchemaChangePolicy.DeleteBehavior
は、ドキュメントだと指定は必須となっていませんが、指定しない場合になぜか下記のエラーとなるのでLOG
を指定しています。
The SchemaChangePolicy for catalog targets can have only LOG DeleteBehavior value. Specify a value of LOG for the DeleteBehavior property.
クロール対象とするGlueテーブルDevicesRawDataGlueTable
のリソース定義では、Properties.TableInput.PartitionKeys
にてyear
、month
、day
の3つをパーティションキーとして指定しています。
スタックをデプロイします。
% aws cloudformation deploy \ --template-file template.yaml \ --stack-name devices-data-analytics-stack \ --capabilities CAPABILITY_NAMED_IAM \ --no-fail-on-empty-changeset
データソースへのデータ作成
データソースのデータとして、Hive形式のパーティションパスを持つオブジェクトをS3バケットに作成します。
{"device_id": "3ff9c44a", "timestamp": 1609348014, "state": true}
% aws s3 cp raw-data.json \ ${RAW_DATA_BUCKET}/raw-data/year=2021/month=01/day=13/raw-data.json
動作確認
クローラー実行前はGlueテーブルにパーティションは一つも作成されていません。
% aws glue get-partitions \ --database-name ${GLUE_DATABASE_NAME} \ --table-name ${RAW_DATA_GLUE_TABLE_NAME} { "Partitions": [] }
クローラーを実行します。
% aws glue start-crawler --name ${CRAWLER_NAME}
クローラーのステートがREADY
となれば実行は完了です。
% aws glue get-crawler --name ${CRAWLER_NAME} \ --query Crawler.State "READY"
再度Glueテーブルのパーティションを取得してみると、アップロードしたオブジェクトで指定したパスのパーティションが作成されています。
% aws glue get-partitions \ --database-name ${GLUE_DATABASE_NAME} \ --table-name ${RAW_DATA_GLUE_TABLE_NAME} \ --query 'Partitions[0].Values' [ "2021", "01", "13" ]
おわりに
既存のGlueテーブルに対するクローラーをCloudFormationで作成してみました。
当初クローラーで自動更新を行いたいGlueテーブルはクローラーで作成しないといけないと思い込んでいましたが、調査・検証してみると既存のGlueテーブルの更新にも対応していて良かったです。
参考
- Glueの使い方的な⑭(クローラー(Crawler)のSchemaChangePolicyその1) - Qiita
- [AWS Glue]データカタログのパーティションをAWS CLIで更新してみた | Developers.IO
- start-crawler — AWS CLI 1.18.213 Command Reference
- get-crawler — AWS CLI 1.18.213 Command Reference
以上